package com.huanzhidadi.java8inaction.chapter1;

import com.alibaba.fastjson2.JSON;
import com.huanzhidadi.java8inaction.model.Apple;
import com.huanzhidadi.java8inaction.predicate.ApplePredicate;
import com.huanzhidadi.java8inaction.predicate.Predicate;
import com.huanzhidadi.java8inaction.predicate.impl.AppleGreenColorPredicate;
import com.huanzhidadi.java8inaction.predicate.impl.AppleHeavyWeightPredicate;
import com.huanzhidadi.java8inaction.predicate.impl.AppleRedAndHeavyPredicate;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class AppleTest {

    /**
     * 过滤出绿色的苹果
     * @param inventory
     * @return
     */
    public static List<Apple> filterGreenApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if ("green".equals(apple.getColor())) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 根据传入的颜色过滤苹果
     * @param inventory
     * @param color
     * @return
     */
    public static List<Apple> filterApplesByColor(List<Apple> inventory, String color) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (color.equals(apple.getColor())) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 根据传入的重量过滤苹果
     * @param inventory
     * @param weight
     * @return
     */
    public static List<Apple> filterApplesByWeight(List<Apple> inventory, int weight) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (apple.getWeight() > weight) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 分别根据传入的每个属性进行筛选
     * @param inventory
     * @param color
     * @param weight
     * @param flag
     * @return
     */
    public static List<Apple> filterApplesByProp(List<Apple> inventory, String color, int weight, boolean flag) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if ((flag && color.equals(apple.getColor()))
            || (!flag && apple.getWeight() > weight)) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 根据抽象条件进行筛选
     * @param inventory
     * @param p
     * @return
     */
    public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            // 谓词对象封装了测试苹果的条件
            if (p.test(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * List类型抽象化
     * @param list
     * @param p
     * @return
     */
    public static <T> List<T> filter(List<T> list, Predicate<T> p) {
        List<T> result = new ArrayList<>();
        for (T t : list) {
            // 谓词对象封装了测试苹果的条件
            if (p.test(t)) {
                result.add(t);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        List<Apple> inventory = Arrays.asList(
                new Apple(80, "green"),
                new Apple(155, "green"),
                new Apple(122, "red"));

        List<Apple> result = new ArrayList<>();

        log.info("对绿色苹果进行筛选：");
        result = AppleTest.filterGreenApples(inventory);
        log.info(JSON.toJSONString(result));

        log.info("根据传入的颜色进行筛选：");
        result = AppleTest.filterApplesByColor(inventory, "red");
        log.info(JSON.toJSONString(result));

        log.info("根据传入的重量进行筛选：");
        result = AppleTest.filterApplesByWeight(inventory, 120);
        log.info(JSON.toJSONString(result));

        log.info("对能想到的每个属性进行筛选：");
        result = AppleTest.filterApplesByProp(inventory, "green", 0, true);
        log.info(JSON.toJSONString(result));

        log.info("根据抽象条件筛选：");
        result = AppleTest.filterApples(inventory, new AppleGreenColorPredicate());
        log.info(JSON.toJSONString(result));

        result = AppleTest.filterApples(inventory, new AppleHeavyWeightPredicate());
        log.info(JSON.toJSONString(result));

        result = AppleTest.filterApples(inventory, new AppleRedAndHeavyPredicate());
        log.info(JSON.toJSONString(result));

        log.info("匿名类：");
        result = AppleTest.filterApples(inventory, new ApplePredicate() {
            @Override
            public boolean test(Apple apple) {
                return apple.getWeight() > 150;
            }
        });
        log.info(JSON.toJSONString(result));

        log.info("lambda表达式：");
        result = AppleTest.filterApples(inventory, (Apple apple) -> "green".equals(apple.getColor()));
        log.info(JSON.toJSONString(result));


        log.info("List类型抽象化：");
        result = AppleTest.filter(inventory, (Apple apple) -> "red".equals(apple.getColor()));
        log.info(JSON.toJSONString(result));



    }

}
